package com.kifas.service.dataaccess;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.kifas.entity.BukuPiutangEntity;
import com.kifas.entity.CustomerEntity;
import com.kifas.entity.PiutangEntity;

@Repository
public class PiutangDao {

	@Autowired
	private SessionFactory sessionFactory;

	private static final String ALL_PIUTANG = "from PiutangEntity piutang ";
	private static final String PIUTANG_BY_ID = ALL_PIUTANG + " where piutang.idPiutang = :idPiutang";
	private static final String PIUTANG_BY_NOREF = ALL_PIUTANG + " where piutang.noReferensi = :noReferensi";
	private static final String ALL_BUKU_PIUTANG = "from BukuPiutangEntity bp ";
	private static final String BUKU_PIUTANG_BY_PIUTANG = ALL_BUKU_PIUTANG + " where bp.piutang = :piutang";
	private static final String BUKU_PIUTANG_BY_ID = ALL_BUKU_PIUTANG + " where bp.idBukuPiutang = :idBukuPiutang";
	private static final String BUKU_PIUTANG_LATEST = BUKU_PIUTANG_BY_PIUTANG + " order by bp.tanggal desc";
	private static final String PIUTANG_BY_CUSTOMER = ALL_PIUTANG + " where piutang.customer = :customer";
	private static final String PIUTANG_JATUH_TEMPO = ALL_PIUTANG + " where piutang.tanggalJatuhTempo <= :tanggalJatuhTempo";

	public void insert(PiutangEntity piutang) throws Exception {
		sessionFactory.getCurrentSession().save(piutang);
		if (piutang.getBukuPiutangs() != null) {
			for (BukuPiutangEntity bukuPiutang : piutang.getBukuPiutangs()) {
				insert(bukuPiutang);
			}
		}
	}

	public void insert(BukuPiutangEntity bukuPiutang) throws Exception {
		sessionFactory.getCurrentSession().save(bukuPiutang);
	}

	public void update(PiutangEntity piutang) throws Exception {
		sessionFactory.getCurrentSession().update(piutang);
	}

	@SuppressWarnings("unchecked")
	public List<PiutangEntity> getPiutangs() {
		return sessionFactory.getCurrentSession().createQuery(ALL_PIUTANG).list();
	}

	@SuppressWarnings("unchecked")
	public List<PiutangEntity> getPiutangs(Date start, Date end) {
		return sessionFactory.getCurrentSession().createQuery(ALL_PIUTANG + " where piutang.tanggal between :start and :end")
				.setDate("start", start)
				.setDate("end", end).list();
	}

	public PiutangEntity getPiutang(Long idPiutang) {
		return (PiutangEntity) sessionFactory.getCurrentSession().createQuery(PIUTANG_BY_ID).setLong("idPiutang", idPiutang).uniqueResult();
	}

	@SuppressWarnings("unchecked")
	public List<PiutangEntity> getPiutangByNoRef(String noref) {
		return sessionFactory.getCurrentSession().createQuery(PIUTANG_BY_NOREF).setString("noReferensi", noref).list();
	}

	@SuppressWarnings("unchecked")
	public List<BukuPiutangEntity> getBukuPiutangs() {
		return sessionFactory.getCurrentSession().createQuery(ALL_BUKU_PIUTANG).list();
	}

	@SuppressWarnings("unchecked")
	public List<BukuPiutangEntity> getBukuPiutangs(boolean posting) {
		if(posting)
			return sessionFactory.getCurrentSession().createQuery(ALL_BUKU_PIUTANG + " where bp.posting = '1'").list();
		else
			return sessionFactory.getCurrentSession().createQuery(ALL_BUKU_PIUTANG + " where bp.posting = '0'").list();
	}
	
	public BukuPiutangEntity getBukuPiutang(Long idBukuPiutang) {
		return (BukuPiutangEntity) sessionFactory.getCurrentSession().createQuery(BUKU_PIUTANG_BY_ID).setLong("idBukuPiutang", idBukuPiutang).uniqueResult();
	}

	public void update(BukuPiutangEntity bukuPiutang) throws Exception {
		sessionFactory.getCurrentSession().update(bukuPiutang);
	}

	@SuppressWarnings("unchecked")
	public List<BukuPiutangEntity> getBukuPiutangs(PiutangEntity piutang) {
		return sessionFactory.getCurrentSession().createQuery(BUKU_PIUTANG_BY_PIUTANG).setEntity("piutang", piutang).list();
	}

	@SuppressWarnings("unchecked")
	public List<PiutangEntity> getPiutangs(CustomerEntity customer) {
		return sessionFactory.getCurrentSession().createQuery(PIUTANG_BY_CUSTOMER).setEntity("customer", customer).list();
	}

	@SuppressWarnings("unchecked")
	public List<PiutangEntity> getPiutangs(int days) {
		Calendar tanggalJatuhTempo = new GregorianCalendar();
		if (days != 0) days = days * -1;
		tanggalJatuhTempo.add(Calendar.DATE, days);
		return sessionFactory.getCurrentSession().createQuery(PIUTANG_JATUH_TEMPO).setDate("tanggalJatuhTempo", tanggalJatuhTempo.getTime()).list();
	}

	public BukuPiutangEntity getLatestBukuPiutang(PiutangEntity piutang) {
		return (BukuPiutangEntity) sessionFactory.getCurrentSession().createQuery(BUKU_PIUTANG_LATEST).setEntity("piutang", piutang).list().get(0);
	}

}
